#include <stdio.h>

#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"

#include "hi_io.h"
#include "hi_gpio.h"

#define DELAY_100MS 100*1000
#define DELAY_10MS 10*1000
#define DELAY_2S    2*1000*1000

#define LED_PORT HI_GPIO_IDX_9
#define KEY_PORT HI_GPIO_IDX_5

uint8_t key_flag = 0;

/**
 * @brief GPIO interrupt handling function
 * 
 * @param arg 
 */
static void GPIOIsr(char *arg)
{
    (void)arg;

    if(key_flag == 0)
        key_flag = 1;
}

static void *GPIOTask(const char *arg)
{
    (void)arg;

    static uint8_t led_states;
    uint16_t count = 0;

    /** GPIO initialize **/
    hi_gpio_init();
    
    /** Set the function of pin 09 to GPIO **/
    hi_io_set_func(LED_PORT, HI_IO_FUNC_GPIO_9_GPIO);
    /** Set GPIO 09 direction to output **/
    hi_gpio_set_dir(LED_PORT, HI_GPIO_DIR_OUT);
    /** Set GPIO 09 output to Low**/
    hi_gpio_set_ouput_val(LED_PORT, 0);

    /** Set the function of pin 05 to GPIO **/
    hi_io_set_func(KEY_PORT, HI_IO_FUNC_GPIO_5_GPIO);
    /** Set pin 05 to Pull Up **/
    hi_io_set_pull(KEY_PORT,HI_IO_PULL_UP);
    /** Set GPIO 05 direction to input **/
    hi_gpio_set_dir(KEY_PORT, HI_GPIO_DIR_IN);
    /** Set GPIO 05 Schmitt Trigger **/
    hi_io_set_schmitt(KEY_PORT, 1);
    /** Set the interrupt for GPIO 05 **/
    hi_gpio_register_isr_function(KEY_PORT, HI_INT_TYPE_EDGE, HI_GPIO_EDGE_FALL_LEVEL_LOW,
                                    GPIOIsr, NULL);
    while(1){
        if(key_flag == 1){
            /** Debounce **/
            usleep(DELAY_100MS);
            key_flag = 0;
            led_states = !led_states;
            /** Change the light **/
            hi_gpio_set_ouput_val(LED_PORT, led_states);
        }
        if(++count == 200){
            count = 0;
            /** Show the program state **/
            printf("GPIOTask Running!\n");
        }
        usleep(DELAY_10MS);
    }

    return NULL;
}

static void GPIOTaskEntry(void)
{
    osThreadAttr_t attr;

    attr.name = "GPIOTask";         
    attr.attr_bits = 0U;            
    attr.cb_mem = NULL;             
    attr.cb_size = 0U;              
    attr.stack_mem = NULL;          
    attr.stack_size = 4096;         
    attr.priority = 11;             

    if (osThreadNew((osThreadFunc_t)GPIOTask, NULL, &attr) == NULL) {
        printf("[GPIOTaskEntry] Failed to create GPIOTask!\n");
    }
}

SYS_RUN(GPIOTaskEntry);
